package com.tz.farmer.service.impl;

import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smartPark.msframe.result.ResultEx;
import com.tz.farmer.enums.ErrorCodeEnum;
import com.tz.farmer.mapper.*;
import com.tz.farmer.model.*;
import com.tz.farmer.service.WebFarmerDataService;
import com.tz.farmer.so.*;
import com.tz.farmer.util.AppSecretConfig;
import com.tz.farmer.util.BeanConvertUtils;
import com.tz.farmer.util.ResultExM;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class WebFarmerDataServiceImpl extends ServiceImpl<BusinessInfoMapper, BusinessInfo> implements WebFarmerDataService {

     Logger logger = LoggerFactory.getLogger(WebFarmerDataServiceImpl.class);

    @Resource
    AuthenticationInfoMapper authenticationInfoMapper;
    @Resource
    DetectionInfoMapper detectionInfoMapper;
    @Resource
    OperateInfoMapper operateInfoMapper;
    @Resource
    TradeInfoMapper tradeInfoMapper;
    @Resource
    ProductInfoMapper productInfoMapper;
    @Resource
    BusinessInfoMapper businessInfoMapper;
    @Resource
    FarmerUserInfoMapper farmerUserInfoMapper;


    @Transactional
    @Override
    public ResultEx addBusinessInfo(BusinessInfoSo so) {
        if(!"".equals(so.getUniscId())){
            int i  = this.count(new QueryWrapper<BusinessInfo>().eq("unisc_id", so.getUniscId()).eq("is_delete",0));
            if(i>0) {
                String substring = so.getUniscId().substring(0, so.getUniscId().length() - 6);
                return ResultEx.builder().makeFailedResult("主体信用代码"+substring+"******已存在");
            }
        }
        BusinessInfo businessInfo = BeanConvertUtils.copyProperties(so, BusinessInfo.class);
        businessInfo.setUpdateTime(LocalDateTime.now());
        boolean save = this.save(businessInfo);
        return save==true ? ResultExM.builder().makeResult(ErrorCodeEnum.ERR_COMMON_SUCCEED,businessInfo):ResultExM.builder().makeFailedResult();
    }

    @Transactional
    @Override
    public ResultEx updateBusinessInfo(BusinessInfoSo so) {
        if(so.getIsDelete()!=null&&so.getIsDelete() == 1){
          int i =  farmerUserInfoMapper.selectCountUser(so.getUniscId());
          if(i>0){
              return ResultExM.builder().makeFailedResult("主体绑定已用户，不可删除");
          }
        }
        BusinessInfo businessInfo = BeanConvertUtils.copyProperties(so, BusinessInfo.class);
        if(!"".equals(so.getId())) {
            boolean flag = this.update(businessInfo, new QueryWrapper<BusinessInfo>().eq("id", so.getId()));
            if(flag)
                return ResultExM.builder().makeResultSuccess();
        }
        return ResultExM.builder().makeFailedResult();
    }

    @Transactional
    @Override
    public ResultEx addAuthenticationInfo(EmptySo so) {

        if(!"".equals(so) && so != null&& so.getList().size()>0){
            for (AuthenticationInfoSo a: so.getList()) {
                int product_name = authenticationInfoMapper.selectCountOne(a.getProductName(),a.getLeadId());
                if(product_name > 0 ){
                    return ResultEx.builder().makeFailedResult("此主体下的"+a.getProductName()+"已被认证");
                }
                AuthenticationInfo authenticationInfo = BeanConvertUtils.copyProperties(a, AuthenticationInfo.class);
                authenticationInfo.setCreateTime(LocalDateTime.now());
                authenticationInfo.setLeadId(so.getId());
                if(null != authenticationInfo){
                    int flag = authenticationInfoMapper.insert(authenticationInfo);
                    if(flag<0){
                        return ResultExM.builder().makeFailedResult();
                    }
                }
            }
        }
        return ResultExM.builder().makeResultSuccess();
    }

    @Override
    public ResultEx getBusinessInfoList(BusinessInfoSo so,String userAccount) {
        if("".equals(so.getStartTime()))  so.setStartTime(null);
        if("".equals(so.getKeyword()))  so.setKeyword(null);
        if("".equals(so.getNameorphone()))  so.setNameorphone(null);
        if("".equals(so.getCity()))  so.setCity(null);
        if("".equals(so.getBusinessAddress()))  so.setBusinessAddress(null);
        int n = (so.getCurrentPage()-1)*so.getPageSize();
        int m =so.getPageSize();
        String roleName = farmerUserInfoMapper.selectRoleNameByAccount(userAccount);
        String businessCode = null;
        String city = null;
        if("源头主体企业".equals(roleName)){
            businessCode = farmerUserInfoMapper.selectUniscIdByAccount(userAccount);
        }else{
            String  cityName = farmerUserInfoMapper.selectAssressByAccount(userAccount);
            if("台州市".equals(cityName)){
                businessCode = null;
                city = so.getCity();
            }else {
                city = cityName;
            }
        }
        int total = businessInfoMapper.countTotal(businessCode,so.getProperty(), so.getKeyword(), so.getNameorphone(), so.getBusinessAddress(), so.getStartTime(), so.getEndTime(),city);
        List<BusinessInfo> list = businessInfoMapper.getBusinessInfoList(businessCode,so.getProperty(), so.getKeyword(), so.getNameorphone(), so.getBusinessAddress(), so.getStartTime(), so.getEndTime(),city, n, m);


        if(CollectionUtils.isNotEmpty(list)) {
            for (BusinessInfo b : list) {
                Integer leads = authenticationInfoMapper.selectCount(new QueryWrapper<AuthenticationInfo>().eq("lead_id", b.getId()));
                if (leads == null) leads = 0;
                b.setAuthNum(leads);
                Integer lead_id = productInfoMapper.selectCount(new QueryWrapper<ProductInfo>().eq("lead_id", b.getId()));
                if (lead_id == null) lead_id = 0;
                b.setProdNum(lead_id);
            }
        }
            Map<String , Object> map = new HashMap<>();
            map.put("total",total);
            map.put("data",list);
            return ResultExM.builder().makeResult(ErrorCodeEnum.ERR_COMMON_SUCCEED,map);

    }

    @Override
    public ResultEx deleteAuthenticationInfo(EmptySo so) {
        if(!"".equals(so.getId())){
            int id = authenticationInfoMapper.delete(new QueryWrapper<AuthenticationInfo>().eq("id", so.getId()));
            if (id >0) return  ResultExM.builder().makeSuccessResult();

        }
        return ResultExM.builder().makeFailedResult();
    }

    @Transactional
    @Override
    public ResultEx updateAuthenticationInfo(AuthenticationInfoSo so) {
        AuthenticationInfo authenticationInfo = BeanConvertUtils.copyProperties(so, AuthenticationInfo.class);
        int id = authenticationInfoMapper.update(authenticationInfo, new QueryWrapper<AuthenticationInfo>().eq("id", so.getId()));
        return id > 0 ? ResultExM.builder().makeSuccessResult():ResultExM.builder().makeFailedResult();
    }

    @Override
    public ResultEx getAuthenticationInfoByLeadId(AuthenticationInfoSo so) {
        List<AuthenticationInfo> list = authenticationInfoMapper.selectAuthByLeadId(so.getLeadId());
        int total = authenticationInfoMapper.countNum(so.getLeadId());
        Map<String , Object> map = new HashMap<>();
        map.put("total",total);
        map.put("data",list);
        return ResultExM.builder().makeSuccessResult(map);
    }

    @Override
    public ResultEx deleteDetectionInfo(DetectionInfoSo so) {
        int i = detectionInfoMapper.deleteById(so.getId());
        return i>0? ResultExM.builder().makeSuccessResult() : ResultExM.builder().makeFailedResult();
    }

    @Override
    public ResultEx getDetectionInfoList(DetectionInfoSo so) {
        IPage<DetectionInfo> page = detectionInfoMapper.selectPage(new Page<>(so.getCurrentPage(), so.getPageSize()), new QueryWrapper<DetectionInfo>().eq("p_info_id", so.getPInfoId()));
        Map<String , Object> map = new HashMap<>();
        map.put("total",page.getTotal());
        map.put("data",page.getRecords());
        return ResultExM.builder().makeSuccessResult(map);
    }


    @Transactional
    @Override
    public ResultEx updateDetectionInfo(DetectionInfoSo so) {
        DetectionInfo detectionInfo = BeanConvertUtils.copyProperties(so, DetectionInfo.class);
        detectionInfo.setCreateTime(LocalDateTime.now());
        int id = detectionInfoMapper.update(detectionInfo, new QueryWrapper<DetectionInfo>().eq("id", so.getId()));
        return id>0?ResultExM.builder().makeSuccessResult():ResultExM.builder().makeFailedResult();
    }

    @Override
    public ResultEx getOneDetectionInfo(DetectionInfoSo so) {
        DetectionInfo detectionInfo = detectionInfoMapper.selectById(so.getId());
        return detectionInfo != null ? ResultExM.builder().makeSuccessResult(detectionInfo):ResultExM.builder().makeFailedResult();
    }

    @Override
    public ResultEx getOperateInfoList(OperateInfoSo so) {
       int n = (so.getCurrentPage()-1)*so.getPageSize();
        int m =so.getPageSize();
       List<OperateInfoVo> list = operateInfoMapper.selectListByPid(n,m, so.getPInfoId());
       int total = operateInfoMapper.selectCountByPid(so.getPInfoId());
        Map<String , Object> map = new HashMap<>();
        map.put("total",total);
        map.put("data",list);
        return ResultExM.builder().makeSuccessResult(map);
    }


    @Override
    public ResultEx deleteOperateInfo(OperateInfoSo so) {
        int i = operateInfoMapper.delete(new QueryWrapper<OperateInfo>().eq("id", so.getId()));
        return i>0? ResultExM.builder().makeSuccessResult() : ResultExM.builder().makeFailedResult();
    }

    @Override
    public ResultEx getOneOperateInfo(OperateInfoSo so) {
        OperateInfo operateInfo = operateInfoMapper.selectById(so.getId());
        return operateInfo != null ? ResultExM.builder().makeSuccessResult(operateInfo):ResultExM.builder().makeFailedResult();
    }

    @Transactional
    @Override
    public ResultEx updateOperateInfo(OperateInfoSo so) {
        OperateInfo operateInfo  = BeanConvertUtils.copyProperties(so, OperateInfo.class);
        int id = operateInfoMapper.update(operateInfo, new QueryWrapper<OperateInfo>().eq("id", so.getId()));
        return id>0?ResultExM.builder().makeSuccessResult():ResultExM.builder().makeFailedResult();
    }

    @Override
    public ResultEx getTradeInfoList(TradeInfoSo so) {
        IPage<TradeInfo> page = tradeInfoMapper.selectPage(new Page<>(so.getCurrentPage(), so.getPageSize()),new QueryWrapper<TradeInfo>().eq("p_info_id", so.getPInfoId()));
        List<TradeInfo> list = page.getRecords();
        for (TradeInfo t:list) {
            String city = productInfoMapper.selectCityByPid(t.getPInfoId());
            t.setCity(city);
        }
        Map<String , Object> map = new HashMap<>();
        map.put("total",page.getTotal());
        map.put("data",list);
        return ResultExM.builder().makeSuccessResult(map);
    }


    @Override
    public ResultEx deleteTradeInfo(TradeInfoSo so) {
        int i = tradeInfoMapper.delete(new QueryWrapper<TradeInfo>().eq("id", so.getId()));
        return i>0? ResultExM.builder().makeSuccessResult() : ResultExM.builder().makeFailedResult();
    }

    @Override
    public ResultEx getOneTradeInfo(TradeInfoSo so) {
        TradeInfo tradeInfo  = tradeInfoMapper.selectById(so.getId());
        return tradeInfo != null ? ResultExM.builder().makeSuccessResult(tradeInfo):ResultExM.builder().makeFailedResult();
    }

    @Transactional
    @Override
    public ResultEx updateTradeInfo(TradeInfoSo so) {
        TradeInfo tradeInfo = BeanConvertUtils.copyProperties(so, TradeInfo.class);
        int id = tradeInfoMapper.update(tradeInfo, new QueryWrapper<TradeInfo>().eq("id", so.getId()));
        return id>0?ResultExM.builder().makeSuccessResult():ResultExM.builder().makeFailedResult();
    }

    @Transactional
    @Override
    public ResultEx addProductInfo(ProductInfoSo so) {
        if(!"admin".equals(so.getUserAccount())) {
            int isDelete = farmerUserInfoMapper.selectAusinessByAccountIsDelete(so.getUserAccount());
            if (isDelete != 0) {
                return ResultExM.builder().makeResult(205, "主题信息已被删除，不可添加");
            }
        }
        Integer leadId = farmerUserInfoMapper.selectAusinessByAccount(so.getUserAccount());
        ProductInfo productInfo = BeanConvertUtils.copyProperties(so, ProductInfo.class);
        productInfo.setCreateTime(LocalDateTime.now());
        productInfo.setLeadId(leadId);
        int i = productInfoMapper.insert(productInfo);
        if(i>0){
            //添加种植信息
            int insert = 0;
            for (OperateInfoSo o:so.getListOperate()) {
                OperateInfo operateInfo = BeanConvertUtils.copyProperties(o, OperateInfo.class);
                operateInfo.setPInfoId(productInfo.getId());
                operateInfo.setCreateTime(LocalDateTime.now());
                insert = operateInfoMapper.insert(operateInfo);
            }
            if(insert > 0){
                //添加交易信息
                int flag = 0;
                for (TradeInfoSo o:so.getListTrade()) {
                    TradeInfo tradeInfo = BeanConvertUtils.copyProperties(o, TradeInfo.class);
                    tradeInfo.setPInfoId(productInfo.getId());
                    tradeInfo.setCreateTime(LocalDateTime.now());
                    flag = tradeInfoMapper.insert(tradeInfo);
                    if(flag > 0 ) {
                          //添加监测信息
                        DetectionInfo detectionInfo = BeanConvertUtils.copyProperties(so.getDetection(), DetectionInfo.class);
                        detectionInfo.setCreateTime(LocalDateTime.now());
                        detectionInfo.setPInfoId(productInfo.getId());
                        int d = detectionInfoMapper.insert(detectionInfo);
                           if(d > 0){
                               return ResultExM.builder().makeResult(ErrorCodeEnum.ERR_COMMON_SUCCEED);
                           }
                        return ResultExM.builder().makeFailedResult();
                    }
                }
                return ResultExM.builder().makeFailedResult();
            }
            return ResultExM.builder().makeFailedResult();

        }
        return ResultExM.builder().makeFailedResult();
    }

    @Transactional
    @Override
    public ResultEx updateProductInfo(ProductInfoSo so) {
        ProductInfo productInfo = BeanConvertUtils.copyProperties(so, ProductInfo.class);
        int id = productInfoMapper.update(productInfo, new QueryWrapper<ProductInfo>().eq("id", so.getId()));
        return id>0?ResultExM.builder().makeSuccessResult():ResultExM.builder().makeFailedResult();
    }

    @Override
    public ResultEx deleteProductInfo(ProductInfoSo so) {

        int id = productInfoMapper.delete(new QueryWrapper<ProductInfo>().eq("id", so.getId()));
        tradeInfoMapper.delete(new QueryWrapper<TradeInfo>().eq("p_info_id",so.getId()));
        operateInfoMapper.delete(new QueryWrapper<OperateInfo>().eq("p_info_id",so.getId()));
        detectionInfoMapper.delete(new QueryWrapper<DetectionInfo>().eq("p_info_id",so.getId()));
        return id > 0 ? ResultExM.builder().makeSuccessResult():ResultExM.builder().makeFailedResult();
    }

    @Override
    public ResultEx getOneProductInfo(ProductInfoSo so) {
        ProductInfo productInfo = productInfoMapper.selectById(so.getId());
        return productInfo != null ? ResultExM.builder().makeSuccessResult(productInfo):ResultExM.builder().makeFailedResult();
    }

    @Override
    public ResultEx getProductInfoList(ProductInfoSo so,String userAccount) {
        int n = (so.getCurrentPage()-1)*so.getPageSize();
        int m =so.getPageSize();
        Map userRoleMap = getUserRoleInformation(userAccount);
        String businessCode = (String)userRoleMap.get("businessCode");
        String city = (String) userRoleMap.get("city");
        int total = productInfoMapper.countTotal(businessCode,city,so.getId(),so.getBusinessName(),so.getPName(),so.getStartTime(), so.getEndTime());
        List<ProductInfoVo> list = productInfoMapper.selectProductList(businessCode,city,so.getId(),so.getStartTime(),so.getEndTime(),so.getBusinessName(),so.getPName(),n,m);

        if(CollectionUtils.isNotEmpty(list)){
            for (ProductInfoVo p:list) {
                Integer a = detectionInfoMapper.selectCount(new QueryWrapper<DetectionInfo>().eq("p_info_id", p.getId()).last("and url  != '' "));
                if(a == null) a=0;
                p.setCNum(a);
                Integer b = operateInfoMapper.selectCount(new QueryWrapper<OperateInfo>().eq("p_info_id", p.getId()));
                if(b == null) b=0;
                p.setZNum(b);
                Integer c = tradeInfoMapper.selectCount(new QueryWrapper<TradeInfo>().eq("p_info_id", p.getId()));
                if(c == null) c=0;
                p.setJNum(c);
            }
        }
            Map<String , Object> map = new HashMap<>();
            map.put("total",total);
            map.put("data",list);
            return ResultExM.builder().makeResult(ErrorCodeEnum.ERR_COMMON_SUCCEED,map);

    }

    @Override
    public ResultEx getProductInformation(ProductInfoSo so) {
        int n = (so.getCurrentPage()-1)*so.getPageSize();
        int m =so.getPageSize();
        List<ProductInfo> list = productInfoMapper.selectByLeadId(so.getLeadId(),n,m);
        int total = productInfoMapper.countNum(so.getLeadId());
        Map<String , Object> map = new HashMap<>();
        map.put("total",total);
        map.put("data",list);
        return ResultExM.builder().makeSuccessResult(map);
    }

    @Transactional
    @Override
    public ResultEx addDetection(DetectionInfoSo so) {
        DetectionInfo detectionInfo = BeanConvertUtils.copyProperties(so, DetectionInfo.class);
        detectionInfo.setCreateTime(LocalDateTime.now());
        int insert = detectionInfoMapper.insert(detectionInfo);
        if(insert>0){
            return ResultEx.builder().makeSuccessResult();
        }
        return ResultEx.builder().makeFailedResult();

    }

    @Override
    public ResultEx addTrade(TradeSo so) {
        for (TradeInfoSo o : so.getList()) {
            TradeInfo tradeInfo = BeanConvertUtils.copyProperties(o, TradeInfo.class);
            tradeInfo.setPInfoId(so.getPInfoId());
            tradeInfo.setCreateTime(LocalDateTime.now());
           int flag = tradeInfoMapper.insert(tradeInfo);
            if (flag < 0) {
                return ResultExM.builder().makeFailedResult();
            }
        }
        return ResultExM.builder().makeResult(ErrorCodeEnum.ERR_COMMON_SUCCEED);
    }

    @Override
    public ResultEx addOperate(OperateSo so) {
        for (OperateInfoSo o:so.getList()) {
            OperateInfo operateInfo = BeanConvertUtils.copyProperties(o, OperateInfo.class);
            operateInfo.setPInfoId(so.getPInfoId());
            operateInfo.setCreateTime(LocalDateTime.now());
           int insert = operateInfoMapper.insert(operateInfo);
            if (insert < 0) {
                return ResultExM.builder().makeFailedResult();
            }
        }
        return ResultExM.builder().makeResult(ErrorCodeEnum.ERR_COMMON_SUCCEED);
    }

    private Map getUserRoleInformation(String userAccount) {
        String roleName = farmerUserInfoMapper.selectRoleNameByAccount(userAccount);
        String businessCode = null;
        String city = null;
        if("源头主体企业".equals(roleName)){
            businessCode = farmerUserInfoMapper.selectUniscIdByAccount(userAccount);
        }else{
            String  cityName = farmerUserInfoMapper.selectAssressByAccount(userAccount);
            if("台州市".equals(cityName)){
                businessCode = null;
                city = null;
            }else {
                city = cityName;
            }
        }
        Map<String , Object> map = new HashMap<>();
        map.put("businessCode",businessCode);
        map.put("city",city);
        return map;
    }



}
